function MethodHead(req) {
	
	var path, params, internalParams, methodName;
	var ef = IOFactory.createEncodingFacade();
	
	AbstractRequest.call(this, req);

	this.getNonMethodPath = function() {
		return path;
	}
	
	this.getParams = function() {
		return params;
	}
	
	this.getInternalParams = function() {
		return internalParams;
	}
		
	this.getMethodName = function() {
		return methodName;
	}

	function decode(src) {
		if(src == "")
			return [];

		var parameters = src.split("&");
		var ret = [];
		
		for(var i = 0; i < parameters.length; i++) {
			var pair = parameters[i].split("=");
			var t = new Type(pair[0]);

			ret[i] = new TypedObject(t, pair.length > 1 && ef.isDecodeable(t)? ef.decode(t, pair[1]) : null);
		}
		
		return ret;
	}

	//CONSTRUCTOR
	/*		
		path = req.getPath();

		int pathIndex = path.lastIndexOf('/') + 1;
		int internalIndex = path.indexOf(';', pathIndex);	
		int paramIndex = path.indexOf('?', internalIndex > -1? internalIndex : pathIndex);
		
		methodName = path.substring(pathIndex, internalIndex > -1? internalIndex : paramIndex);
		
		internalParams = internalIndex < 0? new TypedObject[0] : decode(path.substring(internalIndex + 1, paramIndex));
		params = decode(path.substring(paramIndex + 1));
		
		path = path.substring(0, pathIndex);
	 */
	path = req.getPath();

	var pathIndex = path.lastIndexOf('/') + 1;
	var internalIndex = path.indexOf(';', pathIndex);
	var paramIndex = path.indexOf('?', internalIndex > -1? internalIndex : pathIndex);

	methodName = path.substring(pathIndex, internalIndex > -1? internalIndex : paramIndex);

	internalParams = internalIndex < 0? [] : decode(path.substring(internalIndex + 1, paramIndex));

	params = decode(path.substring(paramIndex + 1, path.length));
	
	path = path.substring(0, pathIndex);

}


function MethodHeadInitNoArgs(method_name, req) {
	MethodHeadInit.call(this,method_name,[],[],req);
}
function MethodHeadInit(methodName, params, internalParams, req) {
	var path;
	var ef = IOFactory.createEncodingFacade();
	var methodPath = req.getPath();
	var internalEncoded = encode(internalParams, ";", false);
	var paramsEncoded = encode(params, "?", true);
	
	if (!(methodPath.charAt(methodPath.length - 1) == "/")) 
		methodPath += "/";

	path = methodPath;
	
	if (internalEncoded != []) 
		methodPath += methodName + internalEncoded + paramsEncoded;
	else 
		methodPath += methodName + paramsEncoded;
	
	AbstractRequest.call(this, new RequestHeadInit(req.getHTTPMethod(), methodPath, req));

	this.getNonMethodPath = function() {
		return path;
	}
	
	this.getParams = function() {
		return params;
	}
	
	this.getInternalParams = function() {
		return internalParams;
	}
		
	this.getMethodName = function() {
		return methodName;
	}

	function encode(parameters, init, includeOnEmpty) {
		var methodPath = "";
		
		for(var i = 0; i < parameters.length; i++) {
			var p = parameters[i];
			
			if(!ef.isEncodeable(p.getType())) 
				continue;
		
			if(methodPath != "") 
				methodPath += "&";
			
			var enc = ef.encode(p.getType(), p.getObject());
			methodPath += p.getType().asString() + (enc.length == 0? "" : "=" + enc);
		}
		
		return methodPath == "" && !includeOnEmpty? "" : init + methodPath;
	}
	
}
